package com.klikmee.sms.chat.web.filters;

import java.text.MessageFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Random;

import org.apache.log4j.Logger;

import com.klikmee.sms.cef.services.Service;
import com.klikmee.sms.chat.web.dao.ChatMemberDao;
import com.klikmee.sms.chat.web.dao.SubscriberDAO;
import com.klikmee.sms.services.chat.model.ChatMember;
import com.klikmee.sms.services.chat.model.Question;
import com.klikmee.sms.services.chat.model.Subscriber;

/**
 * Subscribes customer to list of available people for chat. After subscription list of available poeople aliases is sent back to the subscriber.
 * 
 * @author makcro
 * 
 */
public class SubscriptionFilter extends AbstractFilter {

	/**
	 * Core id of the subscription service
	 */
	private Long subsciptionServiceId;

	/**
	 * charging for the subscription message response
	 */
	private Long chargingId;
	/**
	 * Logger instance
	 */
	private Logger logger = Logger.getLogger(SubscriptionFilter.class);

	/**
	 * Reference to the {@link ChatMember} DAO service
	 */
	private ChatMemberDao chatMemberDao = null;

	/**
	 * String template for the reply message
	 */
	private String messageTemplate = null;

	/**
	 * Instance of subsciber dao used to register new / update subscribers
	 */
	private SubscriberDAO subscriberDAO = null;

	/**
	 * number of chat members to return to subscriber
	 */
	private int answerListSize;

	/**
	 * Subscribes customer to members list. Activates on request text and keyword successful match.
	 * 
	 * @return true if customer is subscribed, false otherwise
	 */
	@Override
	public boolean processMessage(Question question) {

		// test if question matches keyword expression
		if (question.getQuestion().matches(activationExpression)) {

			logger.info(MessageFormat.format("Successful activatoin match on subscription filter message id = [{0}]", question.getCoreID()));

			// create / update subscription
			createOrUpdateSubscription(question.getFromNumber());
			// prepare answer text
			String messageText = createMessageBody();
			// send the answer
			Long coreId = this.coreAdapter.sendMessage(chargingId, subsciptionServiceId, Service.SERVICE_FLAG_SEMANTIC_OK, question.getCoreID(), messageText);

			// create answer object
			persistAnswer(question, messageText, coreId, false);

			// update question so it's not visible to operaters
			question.setVisable(false);
			questionDAO.edit(question);

			return true;
		}

		return false;
	}

	/**
	 * Creates / updates subscriber identified by it's phone number.
	 * 
	 * @param phonenumber
	 */
	private void createOrUpdateSubscription(String phonenumber) {
		// try to find subscriber by it's phonenumber
		Subscriber subscriber = this.subscriberDAO.findByPhonenumber(phonenumber);
		// if it's not found, create new
		if (subscriber == null) {
			subscriber = new Subscriber();
			subscriber.setPhonenumber(phonenumber);
			subscriber.setSubscriptionDate(new Date());
			
			logger.info(MessageFormat.format("Created new subscriber with phone number [{0}]", phonenumber));
		}
		// if is found, extend his subscription
		else {
			subscriber.setUnsubscribed(false);
			subscriber.setSubscriptionDate(new Date());
			
			logger.info(MessageFormat.format("Extened subsription for phone number [{0}]", phonenumber));
		}

		subscriberDAO.edit(subscriber);
	}

	private String createMessageBody() {
		// load all members from database
		List<String> allMembersAliases = chatMemberDao.findAllMembersAliases();
		// shuffle list
		Collections.shuffle(allMembersAliases);
		// randomize number of names returned limited by answer list size
		Random random = new Random();
		int listSize = random.nextInt(getAnswerListSize()) + 1;
		int limit = listSize > allMembersAliases.size() ? allMembersAliases.size() : listSize;

		List<String> truncated = allMembersAliases.subList(0, limit);

		String memberAliases = org.apache.commons.lang.StringUtils.join(truncated, ',');

		String messageText = MessageFormat.format(getMessageTemplate(), memberAliases);
		return messageText;
	}

	public void setChatMemberDao(ChatMemberDao chatMemberDao) {
		this.chatMemberDao = chatMemberDao;
	}

	public void setMessageTemplate(String messageTemplate) {
		this.messageTemplate = messageTemplate;
	}

	public void setAnswerListSize(int answerListSize) {
		this.answerListSize = answerListSize;
	}

	public String getMessageTemplate() {
		return messageTemplate;
	}

	public int getAnswerListSize() {
		return answerListSize;
	}

	public void setSubsciptionServiceId(Long subsciptionServiceId) {
		this.subsciptionServiceId = subsciptionServiceId;
	}

	public void setChargingId(Long chargingId) {
		this.chargingId = chargingId;
	}

	public void setSubscriberDAO(SubscriberDAO subscriberDAO) {
		this.subscriberDAO = subscriberDAO;
	}
	

}
